package com.smedi.ismedi.personnel.core.port.adapter.persistence.repository.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.base.Joiner;
import com.smedi.ismedi.database.starter.annotation.SkipSqlPermission;
import com.smedi.ismedi.personnel.core.domain.aggregatemodel.Assignment;
import com.smedi.ismedi.web.starter.util.DozerUtil;
import com.smedi.ismedi.web.starter.util.SegmentateUtil;
import com.smedi.ismedi.personnel.core.port.adapter.persistence.model.AssignmentEntity;
import com.smedi.ismedi.personnel.core.port.adapter.persistence.mybatis.mapper.AssignmentMapper;
import com.smedi.ismedi.personnel.core.domain.repository.AssignmentRepository;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Repository;

import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * @Author: xulinjun
 * @Date: 2021-6-8 15:44
 */
@Slf4j
@Repository
@AllArgsConstructor
public class AssignmentRepositoryImpl extends ServiceImpl<AssignmentMapper, AssignmentEntity> implements AssignmentRepository, IService<AssignmentEntity> {
    private final DozerUtil dozerUtil;
    private final SegmentateUtil segmentateUtil;

    @Override
    public Assignment selectByAssignmentId(Long assignmentId) {
        AssignmentEntity row = this.getBaseMapper().selectById(assignmentId);
        return dozerUtil.convertor(row, Assignment.class);
    }

    @Override
    public Assignment doInsert(Assignment data) {
        AssignmentEntity assignmentEntity = dozerUtil.convertor(data, AssignmentEntity.class);
        this.getBaseMapper().insert(assignmentEntity);
        return dozerUtil.convertor(assignmentEntity, Assignment.class);
    }

    @Override
    public Assignment doUpdate(Assignment data) {
        AssignmentEntity assignmentEntity = dozerUtil.convertor(data, AssignmentEntity.class);
        this.getBaseMapper().updateById(assignmentEntity);
        return dozerUtil.convertor(assignmentEntity, Assignment.class);
    }

    @Override
    public int selectAssignmentCountByHrOrganizationId(Long hrOrganizationId) {
        QueryWrapper<AssignmentEntity> wrapper = new QueryWrapper();
        wrapper.eq("hr_organization_id", hrOrganizationId);
        return this.getBaseMapper().selectCount(wrapper);
    }

    @Override
    public Assignment selectByPersonIdAndHrOrganizationId(Long personId, Long hrOrganizationId) {
        QueryWrapper<AssignmentEntity> wrapper = new QueryWrapper();
        wrapper.eq("hr_organization_id", hrOrganizationId)
                .eq("person_id", personId);
        AssignmentEntity assignmentEntity = this.getBaseMapper().selectOne(wrapper);
        return dozerUtil.convertor(assignmentEntity, Assignment.class);
    }

    @Override
    public String selectPyPersonIdAndHrOrganizationIds(Long personId, List<Long> hrOrganizationIds) {
        List<List<?>> segmentation = segmentateUtil.doCut(hrOrganizationIds, 999);
        QueryWrapper<AssignmentEntity> wrapper = new QueryWrapper();
        wrapper.eq("person_id", personId);

        // 循环拼接分割数组
        wrapper.and(con -> {
            for (List<?> list : segmentation) {
                con.or(i -> i.in("hr_organization_id", list));
            }
        });

        List<AssignmentEntity> list = this.getBaseMapper().selectList(wrapper);
        Set<String> jobs = new HashSet<>();
        list.forEach(i -> {
            jobs.add(i.getHrJob());
        });

        if(jobs.isEmpty()){
            return null;
        }
        return Joiner.on(",").skipNulls().join(jobs);
    }

    @Override
    public List<Assignment> selectByPersonId(Long personId) {
        QueryWrapper<AssignmentEntity> wrapper = new QueryWrapper();
        wrapper.eq("person_id", personId).orderByAsc("id");

        List<AssignmentEntity> rows = this.getBaseMapper().selectList(wrapper);
        return dozerUtil.convertor(rows, Assignment.class);
    }

    @Override
    @SkipSqlPermission
    public List<Assignment> selectByPersonIdsSkipSql(List<Long> personIds) {
        QueryWrapper<AssignmentEntity> wrapper = new QueryWrapper<>();
        wrapper.in("person_id", personIds).orderByAsc("id");

        List<AssignmentEntity> rows = this.getBaseMapper().selectList(wrapper);
        return dozerUtil.convertor(rows, Assignment.class);
    }

    @Override
    @SkipSqlPermission
    public List<Assignment> selectByPersonIdSkipSql(Long personId) {
        QueryWrapper<AssignmentEntity> wrapper = new QueryWrapper<>();
        wrapper.eq("person_id", personId).orderByAsc("id");

        List<AssignmentEntity> rows = this.getBaseMapper().selectList(wrapper);
        return dozerUtil.convertor(rows, Assignment.class);
    }

    @Override
    public void doDeleteByPersonId(Long personId) {
        QueryWrapper<AssignmentEntity> wrapper = new QueryWrapper<>();
        wrapper.eq("person_id", personId);

        this.getBaseMapper().delete(wrapper);
    }

    @Override
    public List<Assignment> selectByHrOrganizationId(Long hrOrganizationId) {
        QueryWrapper<AssignmentEntity> wrapper = new QueryWrapper<>();
        wrapper.eq("hr_organization_id", hrOrganizationId);

        return dozerUtil.convertor(this.getBaseMapper().selectList(wrapper), Assignment.class);
    }

    @Override
    @SkipSqlPermission
    public List<Assignment> selectByHrOrganizationIdSkipSql(Long hrOrganizationId) {
        QueryWrapper<AssignmentEntity> wrapper = new QueryWrapper<>();
        wrapper.eq("hr_organization_id", hrOrganizationId);

        return dozerUtil.convertor(this.getBaseMapper().selectList(wrapper), Assignment.class);
    }
}
